package com.syj.qdp.framework.security.core.filter;

import cn.hutool.core.util.StrUtil;
import com.syj.qdp.framework.common.pojo.CommonResult;
import com.syj.qdp.framework.common.util.servlet.ServletUtils;
import com.syj.qdp.framework.security.LoginUser;
import com.syj.qdp.framework.security.config.SecurityProperties;
import com.syj.qdp.framework.security.core.service.SecurityAuthFrameworkService;
import com.syj.qdp.framework.security.core.util.SecurityFrameworkUtils;
import com.syj.qdp.framework.web.handler.GlobalExceptionHandler;
import lombok.RequiredArgsConstructor;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Jwt 登录状态验证，并加入登录状态到上下文
 *
 * @author Lyon
 */
@RequiredArgsConstructor
public class JwtTokenAuthenticateFilter extends OncePerRequestFilter {

    final SecurityProperties securityProperties;
    final SecurityAuthFrameworkService securityAuthFrameworkService;
    final GlobalExceptionHandler globalExceptionHandler;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        // 登录token 获取
        String authorizationToken = SecurityFrameworkUtils.obtainAuthorizationToken(request, securityProperties.getTokenHeader());
        if (StrUtil.isNotBlank(authorizationToken)) {
            try {
                // 认证并刷新token周期
                LoginUser loginUser = securityAuthFrameworkService.verifyTokenAndRefresh(authorizationToken);
                if (loginUser != null) {
                    // 设置security 上下文状态
                    SecurityFrameworkUtils.setLoginUser(request, loginUser);
                }
            } catch (Exception e) {
                CommonResult<?> commonResult = globalExceptionHandler.allExceptionHandler(request, e);
                ServletUtils.writeJSON(response, commonResult);
            }
        }
        chain.doFilter(request, response);
    }
}
